package com.ccrfid.rmc6.resource.asset;

import com.ccrfid.rmc6.appconfig.exception.pojo.AppException;
import com.ccrfid.rmc6.entity.asset.AssetEntity;
import com.ccrfid.rmc6.lbservice3.mq.MsgDispatcher;
import com.ccrfid.rmc6.pojo.dto.AssetMoveInLocationDto;
import com.ccrfid.rmc6.pojo.dto.LocatorAssetCount;
import com.ccrfid.rmc6.pojo.param.PageParam;
import com.ccrfid.rmc6.repository.search.Criterion;
import com.ccrfid.rmc6.repository.search.SearchCriteria;
import com.ccrfid.rmc6.service.asset.AssetService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.util.StringUtils;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

@Path("assets")
@Produces(MediaType.APPLICATION_JSON)
public class AssetResource {
    private static final Logger logger = LoggerFactory.getLogger(AssetResource.class);
    @Autowired
    private AssetService assetService;
    @Autowired
    private MsgDispatcher msgDispatcher;

    @GET
    public Page<AssetEntity> getAssetsInfoPage(@QueryParam("assetName") String assetName,
                                               @QueryParam("assetSn") String assetSn,
                                               @QueryParam("cardNumber") Long cardNumber,
                                               @QueryParam("enabled") Integer enabled,
                                               @BeanParam PageParam pageParam) {
        SearchCriteria criteria = SearchCriteria.Builder.create();
        if (!StringUtils.isEmpty(assetName)) {
            criteria.add(new Criterion("assetName", Criterion.Operator.LIKE, '%' + assetName + '%'));
        }
        if (!StringUtils.isEmpty(assetSn)) {
            criteria.add(new Criterion("assetSn", Criterion.Operator.LIKE, '%' + assetSn + '%'));
        }
        if (cardNumber != null) {
            criteria.add(new Criterion("cardNumber", Criterion.Operator.EQ, cardNumber));
        }
        if (enabled != null) {
            criteria.add(new Criterion("enabled", Criterion.Operator.EQ, enabled));
        }
        PageRequest pageRequest;
        if (pageParam.getOrders() != null && pageParam.getOrders().size() > 0) {
            pageRequest = PageRequest.of(pageParam.getPageNumber(), pageParam.getPageSize(), Sort.by(pageParam.getOrders()));
        } else {
            pageRequest = PageRequest.of(pageParam.getPageNumber(), pageParam.getPageSize());
        }
        return assetService.getAssetsInfoPage(criteria, pageRequest);
    }

    @GET
    @Path("{id}")
    public AssetEntity getAsset(@PathParam("id") Long assetId) {
        return assetService.getAssetById(assetId);
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public AssetEntity createAsset(AssetEntity entity) throws AppException {
        return assetService.createAsset(entity);
    }

    @PUT
    @Path("{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    public AssetEntity updateAsset(@PathParam("id") Long assetId, AssetEntity entity) throws AppException {
        return assetService.updateAsset(assetId, entity);
    }

    @DELETE
    @Consumes(MediaType.APPLICATION_JSON)
    public Boolean deleteAssets(List<Long> idList) throws AppException {
        return assetService.deleteAssets(idList);
    }

    @PUT
    @Path("{assetId}/binding/{cardNumber}")
    public Boolean bindAssetCard(@PathParam("assetId") Long assetId,
                                 @PathParam("cardNumber") Long cardNumber) throws AppException {
        assetService.bindAssetCard(assetId, cardNumber);
        msgDispatcher.bindAssetCard(assetId, cardNumber);
        return true;
    }

    @DELETE
    @Path("{assetId}/binding/{cardNumber}")
    public Boolean unBindAssetCard(@PathParam("assetId") Long assetId,
                                   @PathParam("cardNumber") Long cardNumber) throws AppException {
        assetService.unBindAssetCard(assetId, cardNumber);
        msgDispatcher.unBindAssetCard(assetId, cardNumber);
        return true;
    }

    @GET
    @Path("distribution")
    public List<LocatorAssetCount> getAssetDistribution(@QueryParam("floorNumber") Integer floorNumber) {
        if (floorNumber != null) {
            return assetService.getAssetDistribution(floorNumber);
        } else {
            return new ArrayList<>();
        }
    }

    @GET
    @Path("{assetId}/level3-move-locations")
    public List<AssetMoveInLocationDto> getAssetMoveLocationList(@PathParam("assetId") Long assetId,
                                                                 @QueryParam("startTime") Timestamp startTime,
                                                                 @QueryParam("endTime") Timestamp endTime) {
        return assetService.getAssetMoveLocationList(assetId, startTime, endTime);
    }
}
